#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>


#include "link_protocol.h"



static linkProtocolType linkProtocolDataBuffer;

static linkProtocolStateType linkProtocolState;


uint16_t packagelinkProtocolToBuffer(uint8_t *buf, uint8_t msgId,uint8_t *msgData, uint16_t msgLen)
{
    int ret = 0;
    if(buf == NULL || msgLen <= 0 || msgLen > 255 || msgData == NULL)
	{
		return ret;
    }

    ret = msgLen + 4;

	//head
    buf[0] = 0xfc;
    buf[1] = msgId;
    buf[2] = msgLen;
    memcpy(&buf[3], msgData, msgLen);

	// init crc
    buf[ret-1] = 0;

    for(int i=1; i<ret-1; i++)
	{
        buf[ret-1] ^= buf[i];
    }

    return ret;
}


static uint8_t linkProtocolMessageParseChar(linkProtocolType *recvMessage, uint8_t c)
{
	linkProtocolState.m_msgReceived = LinkMessageFramingStateIncomplete;

	switch(linkProtocolState.m_parseState)
	{
		case LinkMessageParseStateUninit:
		case LinkMessageParseStateIdle:
			if(c == 0xfc)
			{
				linkProtocolState.m_parseState = LinkMessageParseStateGetStart;
                linkProtocolState.m_packetIdx = 0;
				linkProtocolDataBuffer.m_checksum = 0;
				linkProtocolDataBuffer.m_len = 0;
			}
			break;

		case LinkMessageParseStateGetStart:
			linkProtocolDataBuffer.m_msgid = c;
			linkProtocolDataBuffer.m_checksum ^= c;
			linkProtocolState.m_parseState = LinkMessageParseStateGetMessageId;
			break;

		case LinkMessageParseStateGetMessageId:
			linkProtocolDataBuffer.m_len = c;
			linkProtocolDataBuffer.m_checksum ^= c;
			linkProtocolState.m_parseState = LinkMessageParseStateGetLen;
			break;

		case LinkMessageParseStateGetLen:
			linkProtocolDataBuffer.m_data[linkProtocolState.m_packetIdx++] = c;
			linkProtocolDataBuffer.m_checksum ^= c;
			if(linkProtocolState.m_packetIdx == linkProtocolDataBuffer.m_len)
			{
				linkProtocolState.m_parseState = LinkMessageParseStateGetData;
			}
			break;

		case LinkMessageParseStateGetData:
			if(c == linkProtocolDataBuffer.m_checksum)
			{
				memcpy(recvMessage, &linkProtocolDataBuffer, sizeof(linkProtocolType));
				linkProtocolState.m_msgReceived = LinkMessageFramingStateOk;
			}
			else
			{
				linkProtocolState.m_msgReceived = LinkMessageFramingStateError;
			}
			linkProtocolState.m_parseState = LinkMessageParseStateIdle;
			break;

		default:
			break;
	}

	return linkProtocolState.m_msgReceived;
}




uint8_t handleLinkProtocolData(linkProtocolType *recvMsg, uint8_t c)
{
	uint8_t  msgReceived = linkProtocolMessageParseChar(recvMsg, c);

	if(msgReceived == LinkMessageFramingStateError)
	{
		linkProtocolState.m_parseError++;

		if(c == 0xfc)
		{
			linkProtocolState.m_parseState = LinkMessageParseStateGetStart;
            linkProtocolState.m_packetIdx = 0;
			linkProtocolDataBuffer.m_checksum = 0;
			linkProtocolDataBuffer.m_len = 0;
		}

        return LinkMessageFramingStateIncomplete;
	}

	return msgReceived;
}



